
/**
 @file ctc_vlan_cli.c

 @date 2020-07-28

 @version v1.0

---file comments----
*/


/****************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "ctc_vlan_cli.h"
#include "ctc_cli.h"
#include "ctc_cli_common.h"
#include "ctcs_api.h"
#include "asw/include/drv_api.h"
#include "ctc_diag_cli.h"

CTC_CLI(ctc_cli_asw_vlan_create_vlan_with_vlanptr,
        ctc_cli_asw_vlan_create_vlan_with_vlanptr_cmd,
        "vlan create vlan VLAN_ID  (fid FID |default-entry|) ",
        CTC_CLI_VLAN_M_STR,
        "Create one vlan",
        CTC_CLI_VLAN_DESC,
        CTC_CLI_VLAN_RANGE_DESC,
        "Forwarding ID",
        CTC_CLI_FID_ID_DESC,
        "Default entry")
{
    int32 ret = CLI_SUCCESS;
    uint8 index = 0xFF;
    ctc_vlan_uservlan_t user_vlan;

    sal_memset(&user_vlan, 0, sizeof(ctc_vlan_uservlan_t));

    CTC_CLI_GET_UINT16("vlan id", user_vlan.vlan_id, argv[0]);
    index = CTC_CLI_GET_ARGC_INDEX("fid");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT16("fid", user_vlan.fid, argv[index + 1]);
    }
    index = CTC_CLI_GET_ARGC_INDEX("default-entry");
    if (index != 0xFF)
    {
        user_vlan.fid = user_vlan.vlan_id;
    }
    ret = ctcs_vlan_create_uservlan(g_api_lchip, &user_vlan);
    if (ret < 0)
    {
        ctc_cli_out("%% ret=%d, %s\n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return ret;
}

CTC_CLI(ctc_cli_asw_vlan_remove_vlan,
        ctc_cli_asw_vlan_remove_vlan_cmd,
        "vlan remove vlan VLAN_ID",
        CTC_CLI_VLAN_M_STR,
        "Remove one vlan",
        CTC_CLI_VLAN_DESC,
        CTC_CLI_VLAN_RANGE_DESC)
{
    int32 ret = 0;
    uint16 vlan_id;

    CTC_CLI_GET_UINT16("vlan id", vlan_id, argv[0]);
        ret = ctcs_vlan_destroy_vlan(g_api_lchip, vlan_id);
    if (ret < 0)
    {
        ctc_cli_out("%% ret=%d, %s\n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return ret;
}

 CTC_CLI(ctc_cli_asw_vlan_set_member_port,
        ctc_cli_asw_vlan_set_member_port_cmd,
        "vlan (add |del) port GPHYPORT_ID vlan VLAN_ID ",
        CTC_CLI_VLAN_M_STR,
        "Add member port to vlan",
        "Delete member port from vlan",
        CTC_CLI_GPORT_DESC,
        CTC_CLI_GPHYPORT_ID_DESC,
        CTC_CLI_VLAN_DESC,
        CTC_CLI_VLAN_RANGE_DESC)
{
    int32   ret = 0;
    uint16 vlan_id = 0;
    uint16 gport = 0;
    ctc_port_bitmap_t port_bitmap = {0};

    CTC_CLI_GET_UINT16("vlan id", vlan_id, argv[2]);
    CTC_CLI_GET_UINT32("gport", gport, argv[1]);

    CTC_BIT_SET(port_bitmap[0], gport);

    if (0 == sal_memcmp("a", argv[0], 1))
    {
        ret = ctcs_vlan_add_ports(g_api_lchip, vlan_id, port_bitmap);
    }
    else if (0 == sal_memcmp("d", argv[0], 1))
    {
        ret = ctcs_vlan_remove_ports(g_api_lchip, vlan_id, port_bitmap);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s\n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return ret;
}


CTC_CLI(ctc_cli_asw_vlan_show_vlan_info,
        ctc_cli_asw_vlan_show_vlan_info_cmd,
        "show vlan VLAN_ID (member-port | stpid |tagged-port ) ",
        CTC_CLI_SHOW_STR,
        CTC_CLI_VLAN_DESC,
        CTC_CLI_VLAN_RANGE_DESC,
        "Vlan member port",
        "Stp instance in vlan",
        "Vlan tagged port")
{
    int32 ret = 0;
    ctc_port_bitmap_t port_bitmap = { 0 };
    uint16 vlan_id;
    uint8  gchip = 0;
    uint16 bit_cnt;
    uint16 port_count = 0;
    uint16 portid = 0;
    uint32 max_port_num_per_chip = 28;
    uint8 index = 0xFF;
    uint8 stpid_val = 0;

    CTC_CLI_GET_UINT16("vlan id", vlan_id, argv[0]);
    index = CTC_CLI_GET_ARGC_INDEX("member-port");
    if (0xFF != index)
    {
        ret = ctcs_vlan_get_ports(g_api_lchip, vlan_id, gchip, port_bitmap);
        if (ret < 0)
        {
            ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
            return CLI_ERROR;
        }
        ctc_cli_out("%-8s%-8s%s\n", "No.", "Chip", "Member(gport)");
        ctc_cli_out("------------------------\n");
        for (bit_cnt = 0; bit_cnt < max_port_num_per_chip; bit_cnt++)
        {
            portid = bit_cnt;
            if (CTC_IS_BIT_SET(port_bitmap[0], portid))
            {
                ctc_cli_out("%-8u0x%-8X0x%04X\n", port_count, gchip,  portid);
                port_count++;
            }
        }
        ctc_cli_out("------------------------\n");
        ctc_cli_out("member port count:%u\n\n", port_count);

    }
    index = CTC_CLI_GET_ARGC_INDEX("tagged-port");
    if (0xFF != index)
    {
        ret = ctcs_vlan_get_tagged_ports(g_api_lchip, vlan_id, gchip, port_bitmap);
        if (ret < 0)
        {
            ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
            return CLI_ERROR;
        }
        ctc_cli_out("%-8s%-8s%s\n", "No.", "Chip", "Tagged_Member(gport)");
        ctc_cli_out("-----------------------------\n");
        for (bit_cnt = 0; bit_cnt < max_port_num_per_chip; bit_cnt++)
        {
            portid = bit_cnt;
            if (CTC_IS_BIT_SET(port_bitmap[0], portid))
            {
                ctc_cli_out("%-8u0x%-8X0x%04X\n", port_count, gchip,  portid);
                port_count++;
            }
        }
        ctc_cli_out("-----------------------------\n");
        ctc_cli_out("member port count:%u\n\n", port_count);

    }
    index = CTC_CLI_GET_ARGC_INDEX("stpid");
    if (0xFF != index)
    {
        ret = ctcs_stp_get_vlan_stpid(g_api_lchip, vlan_id, &stpid_val);
        if (ret < 0)
        {
            ctc_cli_out("%% ret = %d, %s \n", ret);
            return CLI_ERROR;
        }
        ctc_cli_out("%-24s%u\n", "stpid", stpid_val);
    }
    return ret;
}

CTC_CLI(ctc_cli_asw_vlan_set_member_ports,
        ctc_cli_asw_vlan_set_member_ports_cmd,
        "vlan (add | del) ports pbmp0 PORT_BITMAP_0 vlan VLAN_ID",
        CTC_CLI_VLAN_M_STR,
        "Add member ports to vlan",
        "Delete member ports from vlan",
        "Local ports",
        CTC_CLI_PORT_BITMAP_DESC,
        CTC_CLI_PORT_BITMAP_VALUE_DESC,
        CTC_CLI_VLAN_DESC,
        CTC_CLI_VLAN_RANGE_DESC)
{
    int32 ret = 0;
    uint16  vlan_id = 0;
    ctc_port_bitmap_t port_bitmap = {0};

    CTC_CLI_GET_UINT32("port bitmap 0", port_bitmap[0], argv[1]);
    CTC_CLI_GET_UINT16("vlan id", vlan_id, argv[2]);

    if (0 == sal_memcmp("add", argv[0], sal_strlen("add")))
    {
            ret = ctcs_vlan_add_ports(g_api_lchip, vlan_id, port_bitmap);
    }
    else if (0 == sal_memcmp("del", argv[0], sal_strlen("del")))
    {
            ret = ctcs_vlan_remove_ports(g_api_lchip, vlan_id, port_bitmap);
    }
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s\n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return CTC_E_NONE;
}

CTC_CLI(ctc_cli_asw_vlan_set_port_tag,
        ctc_cli_asw_vlan_set_port_tag_cmd,
        "vlan VLAN_ID port GPHYPORT_ID (tagged|untagged)",
        CTC_CLI_VLAN_M_STR,
        CTC_CLI_VLAN_RANGE_DESC,
        "Gport id",
        CTC_CLI_GPHYPORT_ID_DESC,
        "Vlan tagged on this port",
        "Vlan untagged on this port")
{
    int32 ret;
    uint16 vlan_id;
    uint16 gport;
    uint8 index = 0;
    ctc_port_bitmap_t port_bitmap = {0};

    CTC_CLI_GET_UINT16("vlan id", vlan_id, argv[0]);
    CTC_CLI_GET_UINT16("gport", gport, argv[1]);

    ret = ctcs_vlan_get_tagged_ports(g_api_lchip, vlan_id, 0, port_bitmap);
    index = CTC_CLI_GET_ARGC_INDEX("tagged");
    if (0xFF != index)
    {
        CTC_BIT_SET(port_bitmap[0], gport);
    }
    else
    {
        CTC_BIT_UNSET(port_bitmap[0], gport);
    }
    ret = ret?ret:ctcs_vlan_set_tagged_ports(g_api_lchip, vlan_id, port_bitmap);

    if (ret < 0)
    {
        ctc_cli_out("%% ret =%d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_asw_vlan_set_ports_tag,
        ctc_cli_asw_vlan_set_ports_tag_cmd,
        "vlan VLAN_ID ports {pbmp0 PORT_BITMAP_0 | pbmp1 PORT_BITMAP_1 | pbmp2 PORT_BITMAP_2 | \
                                     pbmp3 PORT_BITMAP_3 | pbmp4 PORT_BITMAP_4 | pbmp5 PORT_BITMAP_5 | \
                                     pbmp6 PORT_BITMAP_6 | pbmp7 PORT_BITMAP_7 | \
                                     pbmp8 PORT_BITMAP_8 | pbmp9 PORT_BITMAP_9 } tagged",
        CTC_CLI_VLAN_M_STR,
        CTC_CLI_VLAN_RANGE_DESC,
        "Local ports",
        "Bitmap of ports",
        "Bitmap value",
        "Bitmap of ports",
        "Bitmap value",
        "Bitmap of ports",
        "Bitmap value",
        "Bitmap of ports",
        "Bitmap value",
        "Bitmap of ports",
        "Bitmap value",
        "Bitmap of ports",
        "Bitmap value",
        "Bitmap of ports",
        "Bitmap value",
        "Bitmap of ports",
        "Bitmap value",
        "Bitmap of ports",
        "Bitmap value",
        "Bitmap of ports",
        "Bitmap value",
        "Vlan tagged on ports")
{
    int32 ret = 0;
    uint8 index = 0;
    uint16  vlan_id = 0;
    ctc_port_bitmap_t port_bitmap = {0};

    CTC_CLI_GET_UINT16("vlan id", vlan_id, argv[0]);

    index = CTC_CLI_GET_ARGC_INDEX("pbmp0");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT32("port bitmap 0", port_bitmap[0], argv[index + 1]);
    }

    ret = ctcs_vlan_set_tagged_ports(g_api_lchip, vlan_id, port_bitmap);

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s\n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return CTC_E_NONE;

}

#define ___adv_vlan___

CTC_CLI(ctc_cli_asw_vlan_add_vlan_mapping,
        ctc_cli_asw_vlan_add_vlan_mapping_cmd,
        "vlan mapping add port GPORT_ID {svid VLAN_ID (mask MASK|) (to-svid VLAN_ID |) | s-cos COS | cvid VLAN_ID (mask MASK|) (to-cvid VLAN_ID |) | c-cos COS \
        | vrange-grp VRANGE_GROUP_ID | macsa MAC (mask MASK|)| ipv4sa A.B.C.D | ipv6sa X:X::X:X |} \
        mapping-to {new-cvid VLAN_ID | new-scos COS | new-ccos COS | policer-id POLICERID | stats STATS_ID \
        | new-svid VLAN_ID | stag-op TAG_OP (sl-svid TAG_SL|) (sl-scos TAG_SL|) | ctag-op TAG_OP (sl-cvid TAG_SL|) (sl-ccos TAG_SL|) | use-flex |}",
        CTC_CLI_VLAN_M_STR,
        "Vlan mapping",
        "Add vlan mapping entry",
        CTC_CLI_GPORT_DESC,
        CTC_CLI_GPORT_ID_DESC,
        "Stag vlan, or start vlan of vlan range",
        CTC_CLI_VLAN_RANGE_DESC,
        "Mask",
        "MASK 1-0xFFF",
        "Vlan range, end vlan",
        CTC_CLI_VLAN_RANGE_DESC,
        "Stag cos",
        CTC_CLI_COS_RANGE_DESC,
        "Ctag vlan, or start vlan of vlan range",
        CTC_CLI_VLAN_RANGE_DESC,
        "Mask",
        "MASK 1-0xFFF",
        "Vlan range, end vlan",
        CTC_CLI_VLAN_RANGE_DESC,
        "Ctag cos",
        CTC_CLI_COS_RANGE_DESC,
        "Vlan range group id",
        "<0-3>",
        CTC_CLI_MACSA_DESC,
        CTC_CLI_MAC_FORMAT,
        "Mac sa mask",
        "MASK <6 bits for 6 bytes>",
        "IPv4 SA",
        CTC_CLI_IPV4_FORMAT,
        "IPv6 SA",
        CTC_CLI_IPV6_FORMAT,
        "Mapping to",
        "Mapped cvlan",
        "Vlan id value",
        "New stag cos",
        CTC_CLI_COS_RANGE_DESC,
        "New ctag cos",
        CTC_CLI_COS_RANGE_DESC,
        "Policer id",
        "POLICER ID",
        "Statistic",
        CTC_CLI_STATS_ID_VAL,
        "Mapped svlan",
        "Vlan id value",
        "Stag operation type",
        CTC_CLI_TAG_OP_DESC,
        "Svid select",
        CTC_CLI_TAG_SL_DESC,
        "Scos select",
        CTC_CLI_TAG_SL_DESC,
        "Ctag operation type",
        CTC_CLI_TAG_OP_DESC,
        "Cvid select",
        CTC_CLI_TAG_SL_DESC,
        "Ccos select",
        CTC_CLI_TAG_SL_DESC,
        "Use tcam key")
{
    uint8 index = 0xFF;
    uint16 gport = 0;
    int32 ret = 0;
    ctc_vlan_mapping_t vlan_mapping;
    mac_addr_t macsa;
    ipv6_addr_t ipv6_address;

    sal_memset(&vlan_mapping, 0, sizeof(ctc_vlan_mapping_t));
    vlan_mapping.vrange_grpid = 0xff;
    vlan_mapping.key = CTC_VLAN_MAPPING_KEY_NONE;

    CTC_CLI_GET_UINT16_RANGE("gport", gport, argv[0], 0, CTC_MAX_UINT16_VALUE);
    index = CTC_CLI_GET_ARGC_INDEX("use-flex");
    if (0xFF != index)
    {
        vlan_mapping.flag |= CTC_VLAN_MAPPING_FLAG_USE_FLEX;
    }
    index = CTC_CLI_GET_ARGC_INDEX("svid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("svlan id", vlan_mapping.old_svid, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_SVID;
        if (CTC_FLAG_ISSET(vlan_mapping.flag, CTC_VLAN_MAPPING_FLAG_USE_FLEX))
        {
            index = CTC_CLI_GET_ARGC_INDEX("mask");
            if (0xFF != index)
            {
                CTC_CLI_GET_UINT16_RANGE("mask", vlan_mapping.svlan_end, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
            }
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("cvid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("cvlan id", vlan_mapping.old_cvid, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_CVID;
        if (CTC_FLAG_ISSET(vlan_mapping.flag, CTC_VLAN_MAPPING_FLAG_USE_FLEX))
        {
            index = CTC_CLI_GET_ARGC_INDEX("mask");
            if (0xFF != index)
            {
                CTC_CLI_GET_UINT16_RANGE("mask", vlan_mapping.cvlan_end, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
            }
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("macsa");
    if (0xFF != index)
    {
        CTC_CLI_GET_MAC_ADDRESS("source mac address", macsa, argv[index + 1]);

        sal_memcpy(vlan_mapping.macsa, macsa, sizeof(mac_addr_t));
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_MAC_SA;
        if (CTC_FLAG_ISSET(vlan_mapping.flag, CTC_VLAN_MAPPING_FLAG_USE_FLEX))
        {
            index = CTC_CLI_GET_ARGC_INDEX("mask");
            if (0xFF != index)
            {
                CTC_CLI_GET_UINT16_RANGE("mask", vlan_mapping.old_ccos, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
            }
        }
    }


    index = CTC_CLI_GET_ARGC_INDEX("ipv4sa");
    if (0xFF != index)
    {
        CTC_CLI_GET_IPV4_ADDRESS("IPv4 sa", vlan_mapping.ipv4_sa, argv[index + 1]);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_IPV4_SA;
    }

    index = CTC_CLI_GET_ARGC_INDEX("ipv6sa");
    if (0xFF != index)
    {
        CTC_CLI_GET_IPV6_ADDRESS("IPv6 sa", ipv6_address, argv[index + 1]);

        vlan_mapping.ipv6_sa[0] = sal_htonl(ipv6_address[0]);
        vlan_mapping.ipv6_sa[1] = sal_htonl(ipv6_address[1]);
        vlan_mapping.ipv6_sa[2] = sal_htonl(ipv6_address[2]);
        vlan_mapping.ipv6_sa[3] = sal_htonl(ipv6_address[3]);

        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_IPV6_SA;
    }

    index = CTC_CLI_GET_ARGC_INDEX("to-svid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("end svlan", vlan_mapping.svlan_end, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
    }
	
	index = CTC_CLI_GET_ARGC_INDEX("s-cos");
	if (0xFF != index)
	{
		CTC_CLI_GET_UINT16_RANGE("cos", vlan_mapping.old_scos, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_STAG_COS;
	}

    index = CTC_CLI_GET_ARGC_INDEX("to-cvid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("end cvlan", vlan_mapping.cvlan_end, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
    }

	index = CTC_CLI_GET_ARGC_INDEX("c-cos");
	if (0xFF != index)
    {
		CTC_CLI_GET_UINT16_RANGE("cos", vlan_mapping.old_ccos, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_CTAG_COS;
	}

    index = CTC_CLI_GET_ARGC_INDEX("vrange-grp");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("vrange-grp", vlan_mapping.vrange_grpid, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }

    index = CTC_CLI_GET_ARGC_INDEX("new-svid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("new-svid", vlan_mapping.new_svid, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
    }

    index = CTC_CLI_GET_ARGC_INDEX("new-scos");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("new-scos", vlan_mapping.new_scos, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }

    index = CTC_CLI_GET_ARGC_INDEX("new-ccos");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("new-ccos", vlan_mapping.new_ccos, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }

    index = CTC_CLI_GET_ARGC_INDEX("new-cvid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("new-cvid", vlan_mapping.new_cvid, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
    }

    index = CTC_CLI_GET_ARGC_INDEX("policer-id");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("policer-id", vlan_mapping.policer_id, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
    }

    index = CTC_CLI_GET_ARGC_INDEX("stats");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT32_RANGE("stats-id", vlan_mapping.stats_id, argv[index + 1], 0, CTC_MAX_UINT32_VALUE);
        vlan_mapping.action |= CTC_VLAN_MAPPING_FLAG_STATS_EN;
    }

    index = CTC_CLI_GET_ARGC_INDEX("stag-op");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("stag-op", vlan_mapping.stag_op, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }

    index = CTC_CLI_GET_ARGC_INDEX("sl-svid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("sl-svid", vlan_mapping.svid_sl, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }

    index = CTC_CLI_GET_ARGC_INDEX("sl-scos");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("sl-scos", vlan_mapping.scos_sl, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }

    index = CTC_CLI_GET_ARGC_INDEX("ctag-op");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("ctag-op", vlan_mapping.ctag_op, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }

    index = CTC_CLI_GET_ARGC_INDEX("sl-cvid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("sl-cvid", vlan_mapping.cvid_sl, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }

    index = CTC_CLI_GET_ARGC_INDEX("sl-ccos");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("sl-ccos", vlan_mapping.ccos_sl, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }

        ret = ctcs_vlan_add_vlan_mapping(g_api_lchip, gport, &vlan_mapping);

    if (ret < 0)
    {
        ctc_cli_out("%% ret=%d, %s \n", ret, ctc_get_error_desc(ret));
    }

    return ret;
}

CTC_CLI(ctc_cli_asw_vlan_get_vlan_mapping,
        ctc_cli_asw_vlan_get_vlan_mapping_cmd,
        "show vlan mapping port GPORT_ID ({svid VLAN_ID (mask MASK|) (to-svid VLAN_ID |s-cos COS |) | cvid VLAN_ID (mask MASK|) (to-cvid VLAN_ID |c-cos COS |) \
        | vrange-grp VRANGE_GROUP_ID | macsa MAC (mask MASK|) | ipv4sa A.B.C.D | ipv6sa X:X::X:X | use-flex } |)(detail|) ",
        CTC_CLI_SHOW_STR,
        CTC_CLI_VLAN_M_STR,
        "Vlan mapping",
        CTC_CLI_GPORT_DESC,
        CTC_CLI_GPORT_ID_DESC,
        "Stag vlan, or start vlan of vlan range",
        CTC_CLI_VLAN_RANGE_DESC,
        "Mask",
        "MASK 1-4095",
        "Vlan range, end vlan",
        CTC_CLI_VLAN_RANGE_DESC,
        "Stag cos",
        CTC_CLI_COS_RANGE_DESC,
        "Ctag vlan, or start vlan of vlan range",
        CTC_CLI_VLAN_RANGE_DESC,
        "Mask",
        "MASK 1-4095",
        "Vlan range, end vlan",
        CTC_CLI_VLAN_RANGE_DESC,
        "Ctag cos",
        CTC_CLI_COS_RANGE_DESC,
        "Vlan range group id",
        "<0-3>",
        CTC_CLI_MACSA_DESC,
        CTC_CLI_MAC_FORMAT,
        "Mac sa mask",
        "MASK <6 bits for 6 bytes>",
        "IPv4 SA",
        CTC_CLI_IPV4_FORMAT,
        "IPv6 SA",
        CTC_CLI_IPV6_FORMAT,
        "Use tcam key",
        "Detail")
{
    uint8 index = 0xFF;
    uint16 gport = 0;
    int32 ret = 0;
    ctc_vlan_mapping_t vlan_mapping;
    mac_addr_t macsa;
    ipv6_addr_t ipv6_address;
    uint8 is_detail = 0;
    uint16 ad_index = 0;
    uint32 cmd = 0;
    uint8 lchip = g_api_lchip;
    PeCpuAccessHashAddr_m cpu_access_hash_addr;

    sal_memset(&vlan_mapping, 0, sizeof(ctc_vlan_mapping_t));
    vlan_mapping.vrange_grpid = 0xff;
    vlan_mapping.key = CTC_VLAN_MAPPING_KEY_NONE;

    index = CTC_CLI_GET_ARGC_INDEX("use-flex");
    if (0xFF != index)
    {
        vlan_mapping.flag |= CTC_VLAN_MAPPING_FLAG_USE_FLEX;
    }

    index = CTC_CLI_GET_ARGC_INDEX("detail");
    if (index != 0xFF)
    {
        is_detail = 1;
    }
    CTC_CLI_GET_UINT16_RANGE("gport", gport, argv[0], 0, CTC_MAX_UINT16_VALUE);

    index = CTC_CLI_GET_ARGC_INDEX("svid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("svlan id", vlan_mapping.old_svid, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_SVID;
        if (CTC_FLAG_ISSET(vlan_mapping.flag, CTC_VLAN_MAPPING_FLAG_USE_FLEX))
        {
            index = CTC_CLI_GET_ARGC_INDEX("mask");
            if (0xFF != index)
            {
                CTC_CLI_GET_UINT16_RANGE("mask", vlan_mapping.svlan_end, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
            }
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("cvid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("cvlan id", vlan_mapping.old_cvid, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_CVID;
        if (CTC_FLAG_ISSET(vlan_mapping.flag, CTC_VLAN_MAPPING_FLAG_USE_FLEX))
        {
            index = CTC_CLI_GET_ARGC_INDEX("mask");
            if (0xFF != index)
            {
                CTC_CLI_GET_UINT16_RANGE("mask", vlan_mapping.cvlan_end, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
            }
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("macsa");
    if (0xFF != index)
    {
        CTC_CLI_GET_MAC_ADDRESS("source mac address", macsa, argv[index + 1]);

        sal_memcpy(vlan_mapping.macsa, macsa, sizeof(mac_addr_t));
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_MAC_SA;
        if (CTC_FLAG_ISSET(vlan_mapping.flag, CTC_VLAN_MAPPING_FLAG_USE_FLEX))
        {
            index = CTC_CLI_GET_ARGC_INDEX("mask");
            if (0xFF != index)
            {
                CTC_CLI_GET_UINT16_RANGE("mask", vlan_mapping.old_ccos, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
            }
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("ipv4sa");
    if (0xFF != index)
    {
        CTC_CLI_GET_IPV4_ADDRESS("IPv4 sa", vlan_mapping.ipv4_sa, argv[index + 1]);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_IPV4_SA;
    }

    index = CTC_CLI_GET_ARGC_INDEX("ipv6sa");
    if (0xFF != index)
    {
        CTC_CLI_GET_IPV6_ADDRESS("IPv6 sa", ipv6_address, argv[index + 1]);

        vlan_mapping.ipv6_sa[0] = sal_htonl(ipv6_address[0]);
        vlan_mapping.ipv6_sa[1] = sal_htonl(ipv6_address[1]);
        vlan_mapping.ipv6_sa[2] = sal_htonl(ipv6_address[2]);
        vlan_mapping.ipv6_sa[3] = sal_htonl(ipv6_address[3]);

        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_IPV6_SA;
    }

    index = CTC_CLI_GET_ARGC_INDEX("to-svid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("end svlan", vlan_mapping.svlan_end, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
    }
	index = CTC_CLI_GET_ARGC_INDEX("s-cos");
	if (0xFF != index)
	{
		CTC_CLI_GET_UINT16_RANGE("cos", vlan_mapping.old_scos, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_STAG_COS;
    }
    index = CTC_CLI_GET_ARGC_INDEX("to-cvid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("end cvlan", vlan_mapping.cvlan_end, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
    }
    index = CTC_CLI_GET_ARGC_INDEX("c-cos");
	if (0xFF != index)
    {
		CTC_CLI_GET_UINT16_RANGE("cos", vlan_mapping.old_ccos, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_CTAG_COS;
	}
    index = CTC_CLI_GET_ARGC_INDEX("vrange-grp");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("vrange-grp", vlan_mapping.vrange_grpid, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }


    ret = ctcs_vlan_get_vlan_mapping(g_api_lchip, gport, &vlan_mapping);

    if (ret < 0)
    {
        ctc_cli_out("%% ret=%d, %s \n", ret, ctc_get_error_desc(ret));
        return ret;
    }
    ctc_cli_out("\n-----------------------------------------\n");
    if (is_detail)
    {
        sal_memset(&cpu_access_hash_addr, 0, sizeof(PeCpuAccessHashAddr_m));
        cmd = DRV_IOR(PeCpuAccessHashAddr_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, 0, cmd, &cpu_access_hash_addr);
        ad_index = GetPeCpuAccessHashAddr(V, tablePtr_f, &cpu_access_hash_addr);
        switch (vlan_mapping.key
        & (CTC_VLAN_MAPPING_KEY_CVID | CTC_VLAN_MAPPING_KEY_SVID
        | CTC_VLAN_MAPPING_KEY_IPV4_SA | CTC_VLAN_MAPPING_KEY_IPV6_SA | CTC_VLAN_MAPPING_KEY_MAC_SA
        | CTC_VLAN_MAPPING_KEY_STAG_COS | CTC_VLAN_MAPPING_KEY_CTAG_COS))
        {
        case (CTC_VLAN_MAPPING_KEY_CVID):
            ctc_cli_out("xlate_cvlan_key: 0x%x \n", ad_index);
            break;
        case (CTC_VLAN_MAPPING_KEY_SVID):
            ctc_cli_out("xlate_svlan_key: 0x%x \n", ad_index);
            break;
        case (CTC_VLAN_MAPPING_KEY_CVID | CTC_VLAN_MAPPING_KEY_SVID):
            ctc_cli_out("xlate_double_vlan_key: 0x%x \n", ad_index);
            break;
        case (CTC_VLAN_MAPPING_KEY_IPV4_SA):
            ctc_cli_out("xlate_ipv4_key: 0x%x \n", ad_index);
            break;
        case (CTC_VLAN_MAPPING_KEY_IPV6_SA):
            ctc_cli_out("xlate_ipv6_key: 0x%x \n", ad_index);
            break;
        case (CTC_VLAN_MAPPING_KEY_CVID | CTC_VLAN_MAPPING_KEY_CTAG_COS):
            ctc_cli_out("xlate_otag_key: 0x%x \n", ad_index);
            break;
        case (CTC_VLAN_MAPPING_KEY_SVID | CTC_VLAN_MAPPING_KEY_STAG_COS):
            ctc_cli_out("xlate_itag_key: 0x%x \n", ad_index);
            break;
        case (CTC_VLAN_MAPPING_KEY_NONE):
            ad_index = gport + 269;
            ctc_cli_out("port_key: 0x%x \n", ad_index);
            break;
        default:
            return CTC_E_NOT_SUPPORT;
        }
        ctc_cli_out("IvmTable: 0x%x \n", ad_index);
    }
    ctc_cli_out("Vlan mapping action\n");
    ctc_cli_out("-----------------------------------------\n");
    ctc_cli_out("%-30s: %d\n", "New svlan id", vlan_mapping.new_svid);
    ctc_cli_out("%-30s: %d\n", "New svlan cos", vlan_mapping.new_scos);
    ctc_cli_out("%-30s: %d\n", "New cvlan id", vlan_mapping.new_cvid);
    ctc_cli_out("%-30s: %d\n", "New cvlan cos", vlan_mapping.new_ccos);
    /*no corresponding action flag to use*/
    if (vlan_mapping.stag_op)
    {
        ctc_cli_out("%-30s: %d\n", "Svlan operation", vlan_mapping.stag_op);
    }
    if (vlan_mapping.svid_sl)
    {
        ctc_cli_out("%-30s: %d\n", "Svlan selection", vlan_mapping.svid_sl);
    }
    if (vlan_mapping.scos_sl)
    {
        ctc_cli_out("%-30s: %d\n", "Svlan cos selection", vlan_mapping.scos_sl);
    }
    if (vlan_mapping.ctag_op)
    {
        ctc_cli_out("%-30s: %d\n", "Cvlan operation", vlan_mapping.ctag_op);
    }
    if (vlan_mapping.cvid_sl)
    {
        ctc_cli_out("%-30s: %d\n", "Cvlan selection", vlan_mapping.cvid_sl);
    }
    if (vlan_mapping.ccos_sl)
    {
        ctc_cli_out("%-30s: %d\n", "Cvlan cos selection", vlan_mapping.ccos_sl);
    }

    /*no corresponding action flag to use*/
    if (vlan_mapping.policer_id)
    {
        ctc_cli_out("%-30s: %d\n", "Policer id", vlan_mapping.policer_id);
    }

    if (CTC_FLAG_ISSET(vlan_mapping.action, CTC_VLAN_MAPPING_FLAG_STATS_EN))
    {
        ctc_cli_out("%-30s: %d\n", "Stats id", vlan_mapping.stats_id);
    }
    return ret;
}


CTC_CLI(ctc_cli_asw_vlan_update_vlan_mapping,
        ctc_cli_asw_vlan_update_vlan_mapping_cmd,
        "vlan mapping update port GPORT_ID {svid VLAN_ID (mask MASK|) (to-svid VLAN_ID |s-cos COS |) | cvid VLAN_ID (mask MASK|) (to-cvid VLAN_ID |c-cos COS |) \
        | vrange-grp VRANGE_GROUP_ID | macsa MAC (mask MASK|) | ipv4sa A.B.C.D | ipv6sa X:X::X:X | } \
        mapping-to {new-cvid VLAN_ID | new-scos COS | new-ccos COS | policer-id POLICERID | stats STATS_ID \
        | new-svid VLAN_ID | stag-op TAG_OP (sl-svid TAG_SL|) (sl-scos TAG_SL|) | ctag-op TAG_OP (sl-cvid TAG_SL|) (sl-ccos TAG_SL|) |use-flex } ",
        CTC_CLI_VLAN_M_STR,
        "Vlan mapping",
        "Update all actions in vlan mapping entry",
        CTC_CLI_GPORT_DESC,
        CTC_CLI_GPORT_ID_DESC,
        "Stag vlan, or start vlan of vlan range",
        CTC_CLI_VLAN_RANGE_DESC,
        "Mask",
        "MASK 1-0xFFF",
        "Vlan range, end vlan",
        CTC_CLI_VLAN_RANGE_DESC,
        "Stag cos",
        CTC_CLI_COS_RANGE_DESC,
        "Ctag vlan, or start vlan of vlan range",
        CTC_CLI_VLAN_RANGE_DESC,
        "Mask",
        "MASK 1-0xFFF",
        "Vlan range, end vlan",
        CTC_CLI_VLAN_RANGE_DESC,
        "Ctag cos",
        CTC_CLI_COS_RANGE_DESC,
        "Vlan range group id",
        "<0-3>",
        CTC_CLI_MACSA_DESC,
        CTC_CLI_MAC_FORMAT,
        "Mac sa mask",
        "MASK <6 bits for 6 bytes>",
        "IPv4 SA",
        CTC_CLI_IPV4_FORMAT,
        "IPv6 SA",
        CTC_CLI_IPV6_FORMAT,
        "Mapping to",
        "Mapped cvlan",
        CTC_CLI_VLAN_RANGE_DESC,
        "New stag cos",
        CTC_CLI_COS_RANGE_DESC,
        "New ctag cos",
        CTC_CLI_COS_RANGE_DESC,
        "Policer id",
        CTC_CLI_QOS_FLOW_PLC_VAL,
        "Statistic",
        CTC_CLI_STATS_ID_VAL,
        "Mapped svlan",
        CTC_CLI_VLAN_RANGE_DESC,
        "Stag operation type",
        CTC_CLI_TAG_OP_DESC,
        "Svid select",
        CTC_CLI_TAG_SL_DESC,
        "Scos select",
        CTC_CLI_TAG_SL_DESC,
        "Ctag operation type",
        CTC_CLI_TAG_OP_DESC,
        "Cvid select",
        CTC_CLI_TAG_SL_DESC,
        "Ccos select",
        CTC_CLI_TAG_SL_DESC,
        "Use tcam key")
{
    uint8 index = 0xFF;
    uint16 gport = 0;
    int32 ret = 0;
    ctc_vlan_mapping_t vlan_mapping;
    mac_addr_t macsa;
    ipv6_addr_t ipv6_address;

    sal_memset(&vlan_mapping, 0, sizeof(ctc_vlan_mapping_t));
    vlan_mapping.vrange_grpid = 0xff;
    vlan_mapping.key = CTC_VLAN_MAPPING_KEY_NONE;

    CTC_CLI_GET_UINT16_RANGE("gport", gport, argv[0], 0, CTC_MAX_UINT16_VALUE);

    index = CTC_CLI_GET_ARGC_INDEX("use-flex");
    if (0xFF != index)
    {
        vlan_mapping.flag |= CTC_VLAN_MAPPING_FLAG_USE_FLEX;
    }

    index = CTC_CLI_GET_ARGC_INDEX("svid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("svlan id", vlan_mapping.old_svid, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_SVID;
        if (CTC_FLAG_ISSET(vlan_mapping.flag, CTC_VLAN_MAPPING_FLAG_USE_FLEX))
        {
            index = CTC_CLI_GET_ARGC_INDEX("mask");
            if (0xFF != index)
            {
                CTC_CLI_GET_UINT16_RANGE("mask", vlan_mapping.svlan_end, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
            }
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("cvid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("cvlan id", vlan_mapping.old_cvid, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_CVID;
        if (CTC_FLAG_ISSET(vlan_mapping.flag, CTC_VLAN_MAPPING_FLAG_USE_FLEX))
        {
            index = CTC_CLI_GET_ARGC_INDEX("mask");
            if (0xFF != index)
            {
                CTC_CLI_GET_UINT16_RANGE("mask", vlan_mapping.cvlan_end, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
            }
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("macsa");
    if (0xFF != index)
    {
        CTC_CLI_GET_MAC_ADDRESS("source mac address", macsa, argv[index + 1]);

        sal_memcpy(vlan_mapping.macsa, macsa, sizeof(mac_addr_t));
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_MAC_SA;
        if (CTC_FLAG_ISSET(vlan_mapping.flag, CTC_VLAN_MAPPING_FLAG_USE_FLEX))
        {
            index = CTC_CLI_GET_ARGC_INDEX("mask");
            if (0xFF != index)
            {
                CTC_CLI_GET_UINT16_RANGE("mask", vlan_mapping.old_ccos, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
            }
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("ipv4sa");
    if (0xFF != index)
    {
        CTC_CLI_GET_IPV4_ADDRESS("IPv4 sa", vlan_mapping.ipv4_sa, argv[index + 1]);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_IPV4_SA;
    }
    index = CTC_CLI_GET_ARGC_INDEX("ipv6sa");
    if (0xFF != index)
    {
        CTC_CLI_GET_IPV6_ADDRESS("IPv6 sa", ipv6_address, argv[index + 1]);

        vlan_mapping.ipv6_sa[0] = sal_htonl(ipv6_address[0]);
        vlan_mapping.ipv6_sa[1] = sal_htonl(ipv6_address[1]);
        vlan_mapping.ipv6_sa[2] = sal_htonl(ipv6_address[2]);
        vlan_mapping.ipv6_sa[3] = sal_htonl(ipv6_address[3]);

        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_IPV6_SA;
    }
    index = CTC_CLI_GET_ARGC_INDEX("to-svid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("end svlan", vlan_mapping.svlan_end, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
    }
	index = CTC_CLI_GET_ARGC_INDEX("s-cos");
	if (0xFF != index)
	{
		CTC_CLI_GET_UINT16_RANGE("cos", vlan_mapping.old_scos, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_STAG_COS;
    }
    index = CTC_CLI_GET_ARGC_INDEX("to-cvid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("end cvlan", vlan_mapping.cvlan_end, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
    }
    index = CTC_CLI_GET_ARGC_INDEX("c-cos");
	if (0xFF != index)
    {
		CTC_CLI_GET_UINT16_RANGE("cos", vlan_mapping.old_ccos, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_CTAG_COS;
	}
    index = CTC_CLI_GET_ARGC_INDEX("vrange-grp");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("vrange-grp", vlan_mapping.vrange_grpid, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }
    index = CTC_CLI_GET_ARGC_INDEX("new-svid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("new-svid", vlan_mapping.new_svid, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
    }
    index = CTC_CLI_GET_ARGC_INDEX("new-scos");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("new-scos", vlan_mapping.new_scos, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }
    index = CTC_CLI_GET_ARGC_INDEX("new-ccos");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("new-ccos", vlan_mapping.new_ccos, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }
    index = CTC_CLI_GET_ARGC_INDEX("new-cvid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("new-cvid", vlan_mapping.new_cvid, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
    }
    index = CTC_CLI_GET_ARGC_INDEX("policer-id");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("policer-id", vlan_mapping.policer_id, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
    }
    index = CTC_CLI_GET_ARGC_INDEX("stats");
    if (INDEX_VALID(index))
    {
        CTC_CLI_GET_UINT32("stats-id", vlan_mapping.stats_id, argv[index + 1]);
        vlan_mapping.action |= CTC_VLAN_MAPPING_FLAG_STATS_EN;
    }
    index = CTC_CLI_GET_ARGC_INDEX("stag-op");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("stag-op", vlan_mapping.stag_op, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }
    index = CTC_CLI_GET_ARGC_INDEX("sl-svid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("sl-svid", vlan_mapping.svid_sl, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }
    index = CTC_CLI_GET_ARGC_INDEX("sl-scos");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("sl-scos", vlan_mapping.scos_sl, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }
    index = CTC_CLI_GET_ARGC_INDEX("ctag-op");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("ctag-op", vlan_mapping.ctag_op, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }
    index = CTC_CLI_GET_ARGC_INDEX("sl-cvid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("sl-cvid", vlan_mapping.cvid_sl, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }
    index = CTC_CLI_GET_ARGC_INDEX("sl-ccos");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("sl-ccos", vlan_mapping.ccos_sl, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }
    ret = ctcs_vlan_update_vlan_mapping(g_api_lchip, gport, &vlan_mapping);

    if (ret < 0)
    {
        ctc_cli_out("%% ret=%d, %s \n", ret, ctc_get_error_desc(ret));
    }

    return ret;
}

CTC_CLI(ctc_cli_asw_vlan_remove_vlan_mapping,
        ctc_cli_asw_vlan_remove_vlan_mapping_cmd,
        "vlan mapping remove port GPORT_ID {svid VLAN_ID (mask MASK|) (to-svid VLAN_ID (mask MASK|) |s-cos COS |) | cvid VLAN_ID (mask MASK|) (to-cvid VLAN_ID |c-cos COS |) | vrange-grp VRANGE_GROUP_ID | macsa MAC (mask MASK|) | ipv4sa A.B.C.D | ipv6sa X:X::X:X |} (use-flex |) ",
        CTC_CLI_VLAN_M_STR,
        "Vlan mapping",
        "Remove vlan mapping entry",
        CTC_CLI_GPORT_DESC,
        CTC_CLI_GPORT_ID_DESC,
        "802.1ad svlan, or start vlan of vlan range",
        CTC_CLI_VLAN_RANGE_DESC,
        "Mask",
        "MASK 1-0xFFF",
        "Vlan range, end vlan",
        CTC_CLI_VLAN_RANGE_DESC,
        "Stag cos",
        CTC_CLI_COS_RANGE_DESC,
        "802.1ad cvlan, or start vlan of vlan range",
        CTC_CLI_VLAN_RANGE_DESC,
        "Mask",
        "MASK 1-0xFFF",
        "Vlan range, end vlan",
        CTC_CLI_VLAN_RANGE_DESC,
        "Ctag cos",
        CTC_CLI_COS_RANGE_DESC,
        "Vlan range group id",
        "<0-3>",
        CTC_CLI_MACSA_DESC,
        CTC_CLI_MAC_FORMAT,
        "Mac sa mask",
        "MASK <6 bits for 6 bytes>",
        "IPv4 SA",
        CTC_CLI_IPV4_FORMAT,
        "IPv6 SA",
        CTC_CLI_IPV6_FORMAT,
        "Use tcam key")
{
    uint8 index = 0xFF;
    int32 ret = 0;
    uint16 gport = 0;
    mac_addr_t macsa;
    ctc_vlan_mapping_t vlan_mapping;
    ipv6_addr_t ipv6_address;

    sal_memset(&vlan_mapping, 0, sizeof(ctc_vlan_mapping_t));
    vlan_mapping.vrange_grpid=0xff;
    vlan_mapping.key = CTC_VLAN_MAPPING_KEY_NONE;
    CTC_CLI_GET_UINT16_RANGE("gport", gport, argv[0], 0, CTC_MAX_UINT16_VALUE);

    index = CTC_CLI_GET_ARGC_INDEX("use-flex");
    if (0xFF != index)
    {
        vlan_mapping.flag |= CTC_VLAN_MAPPING_FLAG_USE_FLEX;
    }

    index = CTC_CLI_GET_ARGC_INDEX("svid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("svlan id", vlan_mapping.old_svid, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_SVID;
        if (CTC_FLAG_ISSET(vlan_mapping.flag, CTC_VLAN_MAPPING_FLAG_USE_FLEX))
        {
            index = CTC_CLI_GET_ARGC_INDEX("mask");
            if (0xFF != index)
            {
                CTC_CLI_GET_UINT16_RANGE("mask", vlan_mapping.svlan_end, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
            }
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("cvid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("cvlan id", vlan_mapping.old_cvid, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_CVID;
        if (CTC_FLAG_ISSET(vlan_mapping.flag, CTC_VLAN_MAPPING_FLAG_USE_FLEX))
        {
            index = CTC_CLI_GET_ARGC_INDEX("mask");
            if (0xFF != index)
            {
                CTC_CLI_GET_UINT16_RANGE("mask", vlan_mapping.cvlan_end, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
            }
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("to-svid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("end svlan", vlan_mapping.svlan_end, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
    }
	index = CTC_CLI_GET_ARGC_INDEX("s-cos");
	if (0xFF != index)
	{
		CTC_CLI_GET_UINT16_RANGE("cos", vlan_mapping.old_scos, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_STAG_COS;
    }
    index = CTC_CLI_GET_ARGC_INDEX("to-cvid");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16_RANGE("end cvlan", vlan_mapping.cvlan_end, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
    }
    index = CTC_CLI_GET_ARGC_INDEX("c-cos");
	if (0xFF != index)
    {
		CTC_CLI_GET_UINT16_RANGE("cos", vlan_mapping.old_ccos, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_CTAG_COS;
	}
    index = CTC_CLI_GET_ARGC_INDEX("vrange-grp");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("vrange-grp", vlan_mapping.vrange_grpid, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
    }

    index = CTC_CLI_GET_ARGC_INDEX("macsa");
    if (0xFF != index)
    {
        CTC_CLI_GET_MAC_ADDRESS("source mac address", macsa, argv[index + 1]);

        sal_memcpy(vlan_mapping.macsa, macsa, sizeof(mac_addr_t));
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_MAC_SA;
        if (CTC_FLAG_ISSET(vlan_mapping.flag, CTC_VLAN_MAPPING_FLAG_USE_FLEX))
        {
            index = CTC_CLI_GET_ARGC_INDEX("mask");
            if (0xFF != index)
            {
                CTC_CLI_GET_UINT16_RANGE("mask", vlan_mapping.old_ccos, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
            }
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("ipv4sa");
    if (0xFF != index)
    {
        CTC_CLI_GET_IPV4_ADDRESS("IPv4 sa", vlan_mapping.ipv4_sa, argv[index + 1]);
        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_IPV4_SA;
    }

    index = CTC_CLI_GET_ARGC_INDEX("ipv6sa");
    if (0xFF != index)
    {
        CTC_CLI_GET_IPV6_ADDRESS("IPv6 sa", ipv6_address, argv[index + 1]);

        vlan_mapping.ipv6_sa[0] = sal_htonl(ipv6_address[0]);
        vlan_mapping.ipv6_sa[1] = sal_htonl(ipv6_address[1]);
        vlan_mapping.ipv6_sa[2] = sal_htonl(ipv6_address[2]);
        vlan_mapping.ipv6_sa[3] = sal_htonl(ipv6_address[3]);

        vlan_mapping.key |= CTC_VLAN_MAPPING_KEY_IPV6_SA;
    }

    ret = ctcs_vlan_remove_vlan_mapping(g_api_lchip, gport, &vlan_mapping);

    if (ret < 0)
    {
        ctc_cli_out("%% ret=%d, %s \n", ret, ctc_get_error_desc(ret));
    }

    return ret;
}


CTC_CLI(ctc_cli_asw_vlan_add_protocol_vlan,
        ctc_cli_asw_vlan_add_protocol_vlan_cmd,
        "vlan classifier add protocol ether-type ETHER_TYPE vlan VLAN_ID (use-flex|)",
        CTC_CLI_VLAN_M_STR,
        "Vlan classification",
        "Add one vlan classification entry",
        "Protocol based vlan",
        "Ethertype",
        "Legal ether type",
        CTC_CLI_VLAN_DESC,
        CTC_CLI_VLAN_RANGE_DESC,
        "use tcam key")
{
    int32 ret = 0;
    uint16  ether_type = 0;
    ctc_vlan_class_t pro_vlan;
    uint8 index = 0xFF;

    sal_memset(&pro_vlan, 0, sizeof(ctc_vlan_class_t));
    pro_vlan.type = CTC_VLAN_CLASS_PROTOCOL;

    CTC_CLI_GET_UINT16_RANGE("ether-type", ether_type, argv[0], 0, CTC_MAX_UINT16_VALUE);
    pro_vlan.vlan_class.ether_type = ether_type;

    CTC_CLI_GET_UINT16_RANGE("protocol vlan id", pro_vlan.vlan_id, argv[1], 0, CTC_MAX_UINT16_VALUE);
    index = CTC_CLI_GET_ARGC_INDEX("use-flex");
    if (0xFF != index)
    {
        pro_vlan.flag |= CTC_VLAN_CLASS_FLAG_USE_FLEX;
    }
    ret = ctcs_vlan_add_vlan_class(g_api_lchip, &pro_vlan);

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));

        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_asw_vlan_remove_protocol_vlan,
        ctc_cli_asw_vlan_remove_protocol_vlan_cmd,
        "vlan classifier remove protocol ether-type ETHER_TYPE (use-flex|)",
        CTC_CLI_VLAN_M_STR,
        "Vlan classification",
        "Remove one vlan classification entry",
        "Protocol based vlan",
        "Ethertype",
        "Legal ether type",
        "use tcam key")
{
    int32 ret = 0;
    uint16 ether_type = 0;
    ctc_vlan_class_t pro_vlan;
    uint8 index = 0xFF;

    sal_memset(&pro_vlan, 0, sizeof(ctc_vlan_class_t));
    pro_vlan.type = CTC_VLAN_CLASS_PROTOCOL;

    CTC_CLI_GET_UINT16_RANGE("ether-type", ether_type, argv[0], 0, CTC_MAX_UINT16_VALUE);
    pro_vlan.vlan_class.ether_type = ether_type;

    index = CTC_CLI_GET_ARGC_INDEX("use-flex");
    if (0xFF != index)
    {
        pro_vlan.flag |= CTC_VLAN_CLASS_FLAG_USE_FLEX;
    }

    ret = ctcs_vlan_remove_vlan_class(g_api_lchip, &pro_vlan);

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));

        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_asw_vlan_add_mac_vlan_class,
        ctc_cli_asw_vlan_add_mac_vlan_class_cmd,
        "vlan classifier add mac macsa MAC vlan VLAN_ID (use-flex|)",
        CTC_CLI_VLAN_M_STR,
        "Vlan classification",
        "Add one entry",
        "Mac based vlan",
        CTC_CLI_MACSA_DESC,
        CTC_CLI_MAC_FORMAT,
        "Vlan",
        CTC_CLI_VLAN_RANGE_DESC,
        "Use tcam key")
{
    int32 ret;
    uint8 index = 0xFF;
    uint16 vlan_id;
    ctc_vlan_class_t vlan_class;
    mac_addr_t macsa;
    mac_addr_t macda;

    sal_memset(&vlan_class, 0, sizeof(ctc_vlan_class_t));
    sal_memset(&macsa, 0, sizeof(mac_addr_t));
    sal_memset(&macda, 0, sizeof(mac_addr_t));
    vlan_class.type = CTC_VLAN_CLASS_MAC;

    CTC_CLI_GET_MAC_ADDRESS("source mac address", macsa, argv[0]);
    sal_memcpy(&(vlan_class.vlan_class.mac), &macsa, sizeof(mac_addr_t));

    CTC_CLI_GET_UINT16_RANGE("vlan id", vlan_id, argv[1], 0, CTC_MAX_UINT16_VALUE);
    vlan_class.vlan_id = vlan_id;

    index = CTC_CLI_GET_ARGC_INDEX("use-flex");
    if (0xFF != index)
    {
        vlan_class.flag |= CTC_VLAN_CLASS_FLAG_USE_FLEX;
    }

    ret = ctcs_vlan_add_vlan_class(g_api_lchip, &vlan_class);

    if (ret < 0)
    {
        ctc_cli_out("%% ret =%d, %s\n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_asw_vlan_remove_mac_vlan_class,
        ctc_cli_asw_vlan_remove_mac_vlan_class_cmd,
        "vlan classifier remove mac macsa MAC (use-flex|)",
        CTC_CLI_VLAN_M_STR,
        "Vlan classification",
        "Remove one entry",
        "Mac based vlan",
        CTC_CLI_MACSA_DESC,
        CTC_CLI_MAC_FORMAT,
        "Use tcam key")
{
    int32 ret;
    uint8 index = 0xFF;
    ctc_vlan_class_t vlan_class;
    mac_addr_t macsa;
    mac_addr_t macda;

    sal_memset(&vlan_class, 0, sizeof(ctc_vlan_class_t));
    sal_memset(&macsa, 0, sizeof(mac_addr_t));
    sal_memset(&macda, 0, sizeof(mac_addr_t));

    vlan_class.type = CTC_VLAN_CLASS_MAC;

    CTC_CLI_GET_MAC_ADDRESS("source mac address", macsa, argv[0]);
    sal_memcpy(&(vlan_class.vlan_class.mac), &macsa, sizeof(mac_addr_t));

    index = CTC_CLI_GET_ARGC_INDEX("use-flex");
    if (0xFF != index)
    {
        vlan_class.flag |= CTC_VLAN_CLASS_FLAG_USE_FLEX;
    }

    ret = ctcs_vlan_remove_vlan_class(g_api_lchip, &vlan_class);

    if (ret < 0)
    {
        ctc_cli_out("%% ret =%d, %s\n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return ret;
}


CTC_CLI(ctc_cli_asw_vlan_add_ipv4_vlan_class,
        ctc_cli_asw_vlan_add_ipv4_vlan_class_cmd,
        "vlan classifier add ipv4 ip-sa A.B.C.D vlan VLAN_ID {cos COS|use-flex|}",
        CTC_CLI_VLAN_M_STR,
        "Vlan classification",
        "Add one vlan classification entry",
        "IPv4 based vlan",
        "IPv4 source address",
        CTC_CLI_IPV4_FORMAT,
        "Vlan",
        CTC_CLI_VLAN_RANGE_DESC,
        "Cos",
        CTC_CLI_COS_RANGE_DESC,
        "Use tcam key")
{
    uint8 index = 0xFF;
    uint16 vlan_id = 0;
    int32 ret = 0;
    ctc_vlan_class_t vlan_class;

    sal_memset(&vlan_class, 0, sizeof(ctc_vlan_class_t));
    vlan_class.type = CTC_VLAN_CLASS_IPV4;

    index = CTC_CLI_GET_ARGC_INDEX("use-flex");
    if (0xFF != index)
    {
        vlan_class.flag |= CTC_VLAN_CLASS_FLAG_USE_FLEX;
    }
    CTC_CLI_GET_IPV4_ADDRESS("ipv4 source address", vlan_class.vlan_class.ipv4_sa, argv[0]);


    CTC_CLI_GET_UINT16_RANGE("vlan_class id", vlan_id, argv[1], 0, CTC_MAX_UINT16_VALUE);
    vlan_class.vlan_id = vlan_id;

    index = CTC_CLI_GET_ARGC_INDEX("cos");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("cos", vlan_class.cos, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
        vlan_class.flag |= CTC_VLAN_CLASS_FLAG_OUTPUT_COS;
    }

    ret = ctcs_vlan_add_vlan_class(g_api_lchip, &vlan_class);

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
    }

    return ret;
}

CTC_CLI(ctc_cli_asw_vlan_remove_ipv4_vlan_class,
        ctc_cli_asw_vlan_remove_ipv4_vlan_class_cmd,
        "vlan classifier remove ipv4 ip-sa A.B.C.D {use-flex|}",
        CTC_CLI_VLAN_M_STR,
        "Vlan classification",
        "Remove one vlan classification entry",
        "IPv4 based vlan",
        "IPv4 source address",
        CTC_CLI_IPV4_FORMAT,
        "Use tcam key")
{
    uint8 index = 0xFF;
    int32 ret = 0;
    ctc_vlan_class_t vlan_class;

    sal_memset(&vlan_class, 0, sizeof(ctc_vlan_class_t));

    vlan_class.type = CTC_VLAN_CLASS_IPV4;

    index = CTC_CLI_GET_ARGC_INDEX("use-flex");
    if (0xFF != index)
    {
        vlan_class.flag |= CTC_VLAN_CLASS_FLAG_USE_FLEX;
    }
    CTC_CLI_GET_IPV4_ADDRESS("ipv4 source address", vlan_class.vlan_class.ipv4_sa, argv[0]);
    ret = ctcs_vlan_remove_vlan_class(g_api_lchip, &vlan_class);

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
    }

    return ret;
}

CTC_CLI(ctc_cli_asw_vlan_add_ipv6_vlan_class,
        ctc_cli_asw_vlan_add_ipv6_vlan_class_cmd,
        "vlan classifier add ipv6 ip-sa X:X::X:X vlan VLAN_ID {cos COS|use-flex|}",
        CTC_CLI_VLAN_M_STR,
        "Vlan classification",
        "Add one vlan classification entry",
        "IPv6 based vlan",
        "IPv6 source address",
        CTC_CLI_IPV6_FORMAT,
        "Vlan",
        CTC_CLI_VLAN_RANGE_DESC,
        "Cos",
        CTC_CLI_COS_RANGE_DESC,
        "Use tcam key")
{
    uint8 index = 0xFF;
    int32 ret = 0;
    uint16 vlan_id = 0;
    ctc_vlan_class_t vlan_class;
    ipv6_addr_t ipv6_address;

    sal_memset(&vlan_class, 0, sizeof(ctc_vlan_class_t));
    vlan_class.type = CTC_VLAN_CLASS_IPV6;

    index = CTC_CLI_GET_ARGC_INDEX("use-flex");
    if (0xFF != index)
    {
        vlan_class.flag |= CTC_VLAN_CLASS_FLAG_USE_FLEX;
    }

    CTC_CLI_GET_IPV6_ADDRESS("ipv6 source address", ipv6_address, argv[ 0]);
    vlan_class.vlan_class.ipv6_sa[0] = sal_htonl(ipv6_address[0]);
    vlan_class.vlan_class.ipv6_sa[1] = sal_htonl(ipv6_address[1]);
    vlan_class.vlan_class.ipv6_sa[2] = sal_htonl(ipv6_address[2]);
    vlan_class.vlan_class.ipv6_sa[3] = sal_htonl(ipv6_address[3]);

    CTC_CLI_GET_UINT16_RANGE("vlan_class id", vlan_id, argv[1], 0, CTC_MAX_UINT16_VALUE);
    vlan_class.vlan_id = vlan_id;

    index = CTC_CLI_GET_ARGC_INDEX("cos");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT8_RANGE("cos", vlan_class.cos, argv[index + 1], 0, CTC_MAX_UINT8_VALUE);
        vlan_class.flag |= CTC_VLAN_CLASS_FLAG_OUTPUT_COS;
    }
    ret = ctcs_vlan_add_vlan_class(g_api_lchip, &vlan_class);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
    }
    return ret;
}

CTC_CLI(ctc_cli_asw_vlan_remove_ipv6_vlan_class,
        ctc_cli_asw_vlan_remove_ipv6_vlan_class_cmd,
        "vlan classifier remove ipv6 ip-sa X:X::X:X  {use-flex|}",
        CTC_CLI_VLAN_M_STR,
        "Vlan classification",
        "Remove one vlan classification entry",
        "IPv6 based vlan",
        "IPv6 source address",
        CTC_CLI_IPV6_FORMAT,
        "Use tcam key")
{
    uint8 index = 0xFF;
    int32 ret = 0;
    ctc_vlan_class_t vlan_class;
    ipv6_addr_t ipv6_address;

    sal_memset(&vlan_class, 0, sizeof(ctc_vlan_class_t));

    vlan_class.type = CTC_VLAN_CLASS_IPV6;

    index = CTC_CLI_GET_ARGC_INDEX("use-flex");
    if (0xFF != index)
    {
        vlan_class.flag |= CTC_VLAN_CLASS_FLAG_USE_FLEX;
    }
    CTC_CLI_GET_IPV6_ADDRESS("ipv6 source address", ipv6_address, argv[0]);
    vlan_class.vlan_class.ipv6_sa[0] = sal_htonl(ipv6_address[0]);
    vlan_class.vlan_class.ipv6_sa[1] = sal_htonl(ipv6_address[1]);
    vlan_class.vlan_class.ipv6_sa[2] = sal_htonl(ipv6_address[2]);
    vlan_class.vlan_class.ipv6_sa[3] = sal_htonl(ipv6_address[3]);

    ret = ctcs_vlan_remove_vlan_class(g_api_lchip, &vlan_class);

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
    }
    return ret;
}

CTC_CLI(ctc_cli_asw_vlan_create_vlan_vrange,
        ctc_cli_asw_vlan_create_vlan_vrange_cmd,
        "vlan range create vrange-grp GROUP_ID (is-svlan|is-cvlan)",
        CTC_CLI_VLAN_M_STR,
        "Vlan range",
        "Create",
        "Vlan range group id",
        CTC_CLI_VLAN_RANGE_GRP_ID_VALUE,
        "Is svlan range",
        "Is cvlan range")
{
    int32 ret;
    uint8  vrange_grpid = 0;
    bool is_svlan = FALSE;
    ctc_vlan_range_info_t vrange_info;

    sal_memset(&vrange_info, 0, sizeof(ctc_vlan_range_info_t));
    CTC_CLI_GET_UINT8_RANGE("vlan range groupid", vrange_grpid, argv[0], 0, CTC_MAX_UINT8_VALUE);

    if (CLI_CLI_STR_EQUAL("is-svlan", 1))
    {
        is_svlan = TRUE;
    }
    else if (CLI_CLI_STR_EQUAL("is-cvlan", 1))
    {
        is_svlan = FALSE;
    }

    vrange_info.vrange_grpid = vrange_grpid;
    ret = ctcs_vlan_create_vlan_range_group(g_api_lchip, &vrange_info, is_svlan);

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
    }

    return ret;

}

CTC_CLI(ctc_cli_asw_vlan_destroy_vlan_vrange,
        ctc_cli_asw_vlan_destroy_vlan_vrange_cmd,
        "vlan range destroy vrange-grp GROUP_ID ",
        CTC_CLI_VLAN_M_STR,
        "Vlan range",
        "Destroy",
        "Vlan range group id",
        CTC_CLI_VLAN_RANGE_GRP_ID_VALUE)
{
    int32 ret;
    uint8  vrange_grpid = 0;
    ctc_vlan_range_info_t vrange_info;

    CTC_CLI_GET_UINT8_RANGE("vlan range groupid", vrange_grpid, argv[0], 0, CTC_MAX_UINT8_VALUE);

    vrange_info.vrange_grpid = vrange_grpid;

    ret = ctcs_vlan_destroy_vlan_range_group(g_api_lchip, &vrange_info);

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
    }

    return ret;

}


CTC_CLI(ctc_cli_asw_vlan_add_vlan_vrange,
        ctc_cli_asw_vlan_add_vlan_vrange_cmd,
        "vlan range add  MINVID to MAXVID vrange-grp GROUP_ID",
        CTC_CLI_VLAN_M_STR,
        "Vlan range",
        "Add",
        CTC_CLI_VLAN_RANGE_DESC,
        "To",
        CTC_CLI_VLAN_RANGE_DESC,
        "Vlan range group id",
        CTC_CLI_VLAN_RANGE_GRP_ID_VALUE)
{
    int32 ret;
    uint16 vlan_start = 0;
    uint16 vlan_end = 0;
    uint8  vrange_grpid = 0;
    ctc_vlan_range_info_t vrange_info;
    ctc_vlan_range_t vlan_range;

    sal_memset(&vrange_info, 0, sizeof(ctc_vlan_range_info_t));
    sal_memset(&vlan_range, 0, sizeof(ctc_vlan_range_t));
    CTC_CLI_GET_UINT16_RANGE("vlan start", vlan_start, argv[0], 0, CTC_MAX_UINT16_VALUE);
    CTC_CLI_GET_UINT16_RANGE("vlan end", vlan_end, argv[1], 0, CTC_MAX_UINT16_VALUE);
    CTC_CLI_GET_UINT8_RANGE("vlan range groupid", vrange_grpid, argv[2], 0, CTC_MAX_UINT8_VALUE);

    vrange_info.vrange_grpid = vrange_grpid;
    vlan_range.vlan_start = vlan_start;
    vlan_range.vlan_end = vlan_end;
    ret = ctcs_vlan_add_vlan_range(g_api_lchip, &vrange_info, &vlan_range);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
    }

    return ret;

}

CTC_CLI(ctc_cli_asw_vlan_remove_vlan_vrange,
        ctc_cli_asw_vlan_remove_vlan_vrange_cmd,
        "vlan range remove MINVID to MAXVID vrange-grp GROUP_ID",
        CTC_CLI_VLAN_M_STR,
        "Vlan range",
        "Remove",
        CTC_CLI_VLAN_RANGE_DESC,
        "To",
        CTC_CLI_VLAN_RANGE_DESC,
        "Vlan range group id",
        CTC_CLI_VLAN_RANGE_GRP_ID_VALUE)
{
    int32 ret;
    uint16 vlan_start = 0;
    uint16 vlan_end = 0;
    uint8  vrange_grpid = 0;
    ctc_vlan_range_info_t vrange_info;
    ctc_vlan_range_t vlan_range;

    CTC_CLI_GET_UINT16_RANGE("vlan start", vlan_start, argv[0], 0, CTC_MAX_UINT16_VALUE);
    CTC_CLI_GET_UINT16_RANGE("vlan end", vlan_end, argv[1], 0, CTC_MAX_UINT16_VALUE);
    CTC_CLI_GET_UINT8_RANGE("vlan range groupid", vrange_grpid, argv[2], 0, CTC_MAX_UINT8_VALUE);
    vrange_info.vrange_grpid = vrange_grpid;
    vlan_range.vlan_start = vlan_start;
    vlan_range.vlan_end = vlan_end;

    ret = ctcs_vlan_remove_vlan_range(g_api_lchip, &vrange_info, &vlan_range);

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
    }

    return ret;
}

CTC_CLI(ctc_cli_asw_vlan_get_vlan_vrange,
        ctc_cli_asw_vlan_get_vlan_vrange_cmd,
        "show vlan range group GROUP_ID ",
        "Do show",
        CTC_CLI_VLAN_M_STR,
        "Vlan range",
        "Vlan range group id",
        CTC_CLI_VLAN_RANGE_GRP_ID_VALUE)
{
    int32 ret;
    uint8  vrange_grpid = 0;
    uint8 idx = 0;
    ctc_vlan_range_info_t vrange_info;
    ctc_vlan_range_group_t vrange_group;
    uint8 count = 0;
    bool is_svlan = FALSE;
    sal_memset(&vrange_group, 0, sizeof(ctc_vlan_range_group_t));
    CTC_CLI_GET_UINT8_RANGE("vlan range groupid", vrange_grpid, argv[0], 0, CTC_MAX_UINT8_VALUE);
    vrange_info.vrange_grpid = vrange_grpid;

    ret = ctcs_vlan_get_vlan_range(g_api_lchip, &vrange_info, &vrange_group, &count);

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return ret;
    }
    else
    {
        ctc_cli_out("%-20s%-20s%-20s\n", "VRANGE_GRP",  "IS_SVLAN", "VALID_CNT");
        ctc_cli_out("--------------------------------------------------------\n");
        ctc_cli_out("%-20u", vrange_grpid);
        ret = ctcs_vlan_get_vlan_range_type(g_api_lchip, &vrange_info, &is_svlan);

        if (ret < 0)
        {
            ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
            return ret;
        }
        else
        {
            ctc_cli_out("%-20s", is_svlan ? "YES" : "NO");
        }
    }
    ctc_cli_out("%-20u\n", count);

    ctc_cli_out("\nMember Range\n");
    ctc_cli_out("--------------------------\n");
    ctc_cli_out("%-6s%-7s%-7s\n", "No.", "MIN", "MAX");
    for (idx = 0; idx < count; idx++)
    {
        ctc_cli_out("%-6u%-07u%-07u\n", idx, vrange_group.vlan_range[idx].vlan_start, vrange_group.vlan_range[idx].vlan_end);
    }
    return ret;

}

CTC_CLI(ctc_cli_asw_vlan_set_fid,
        ctc_cli_asw_vlan_set_fid_cmd,
        "vlan VLAN_ID fid VRF_ID",
        CTC_CLI_VLAN_M_STR,
        CTC_CLI_VLAN_RANGE_DESC,
        CTC_CLI_FID_DESC,
        CTC_CLI_FID_ID_DESC)
{
    int32 ret;
    uint16 vlan_id;
    uint32 fid;
    ctc_vlan_property_t vlan_prop = CTC_VLAN_PROP_FID;

    CTC_CLI_GET_UINT16("vlan id", vlan_id, argv[0]);
    CTC_CLI_GET_UINT16("vrfid", fid, argv[1]);
    ret = ctcs_vlan_set_property(g_api_lchip, vlan_id, vlan_prop, fid);
    if (ret < 0)
    {
        ctc_cli_out("%% ret =%d, %s\n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return ret;
}


CTC_CLI(ctc_cli_asw_vlan_mapping_all,
        ctc_cli_asw_vlan_mapping_all_cmd,
        "show vlan mapping all",
        CTC_CLI_SHOW_STR,
        CTC_CLI_VLAN_M_STR,
        "Vlan mapping",
        "All")
{
    uint8 lchip = g_api_lchip;
    vlan_mapping_para_t * p_vlan_mapping_para;
    uint32 total_num = 0;
    uint32 tmp_num = 0;
    int32 ret = 0;
    char* vlan_hash_tbl[] = {"XlateMacVlanKey", "XlateMacKey", "XlateIpv4Key", "XlateIpv6Key", "XlateSvlanKey", "XlateDoubleVlanKey","XlateCvlanKey",
                          "XlateOtagKey", "XlateItagKey", "VlanHashView9" , "XlateMacKey0",  "IvmXReg"};

    p_vlan_mapping_para = (vlan_mapping_para_t*)mem_malloc(MEM_CLI_MODULE, sizeof(vlan_mapping_para_t)*MAX_VLAN_REG_TOTAL_NUM);
    if (NULL == p_vlan_mapping_para)
    {
        return CLI_ERROR;
    }
    sal_memset(p_vlan_mapping_para, 0, sizeof(vlan_mapping_para_t)*MAX_VLAN_REG_TOTAL_NUM);
    
    ctc_cli_out("%-8s%-15s%-24s%-10s%-14s\n", "No.", "TABLE_INDEX", "TABLE_NAME","TYPE","AD_INDEX");
    ctc_cli_out("------------------------------------------------------------------\n");
    ctc_cli_asw_vlan_get_mapping_all(vty, lchip, p_vlan_mapping_para, &total_num);
    
    while(tmp_num < total_num)
    {
        if (p_vlan_mapping_para[tmp_num].key_type < VLAN_IVM_X_REG_NUM)
        {
            ctc_cli_out("%-8d%-15d%-24s%-10s%-14d\n", tmp_num, p_vlan_mapping_para[tmp_num].table_index, 
                        vlan_hash_tbl[p_vlan_mapping_para[tmp_num].key_type], "Hash", p_vlan_mapping_para[tmp_num].table_index);
        }
        else
        {
            ctc_cli_out("%-8d%-15d%-24s%-10s%-14d\n", tmp_num, p_vlan_mapping_para[tmp_num].table_index, vlan_hash_tbl[11], 
                        "Tcam",p_vlan_mapping_para[tmp_num].table_index + MAX_VLAN_HASH_REG_NUM);
        }
        tmp_num ++;
    }
    ctc_cli_out("------------------------------------------------------------------\n");
    ctc_cli_out("AD table name: IvmTable\n");
    ctc_cli_out("%-18s%d\n", "Total Entry Num:",MAX_VLAN_REG_TOTAL_NUM);
    ctc_cli_out("%-18s%d\n", "Used Entry Num:",total_num);
    mem_free(p_vlan_mapping_para);
    return ret;
}

        
int32
ctc_asw_vlan_cli_init(uint8 cli_tree_mode)
{
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_create_vlan_with_vlanptr_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_remove_vlan_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_set_member_ports_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_set_member_port_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_show_vlan_info_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_set_port_tag_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_set_ports_tag_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_add_vlan_mapping_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_get_vlan_mapping_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_update_vlan_mapping_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_remove_vlan_mapping_cmd);

    install_element(cli_tree_mode, &ctc_cli_asw_vlan_add_vlan_vrange_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_remove_vlan_vrange_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_get_vlan_vrange_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_create_vlan_vrange_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_destroy_vlan_vrange_cmd);

    install_element(cli_tree_mode, &ctc_cli_asw_vlan_add_protocol_vlan_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_remove_protocol_vlan_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_add_mac_vlan_class_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_remove_mac_vlan_class_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_add_ipv4_vlan_class_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_remove_ipv4_vlan_class_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_add_ipv6_vlan_class_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_remove_ipv6_vlan_class_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_set_fid_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_vlan_mapping_all_cmd);
    

    return CLI_SUCCESS;
}


